prepare($sql); $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (PDOException $e) { error_log("Get classes error: " . $e->getMessage()); return []; } } function getAcademicYears() { global $DBcon; try { $sql = "SELECT academic_year FROM calender ORDER BY academic_year DESC"; $stmt = $DBcon->prepare($sql); $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (PDOException $e) { error_log("Get academic years error: " . $e->getMessage()); return []; } } // CRUD Functions function getAllStudents($filters = [], $page = 1, $per_page = 25) { global $DBcon; try { // Build WHERE clause based on filters $where_clause = ""; $params = []; if (!empty($filters['class_id'])) { $where_clause .= " WHERE class_id = :class_id"; $params[':class_id'] = $filters['class_id']; } if (!empty($filters['admin_year'])) { $where_clause .= empty($where_clause) ? " WHERE" : " AND"; $where_clause .= " admin_year = :admin_year"; $params[':admin_year'] = $filters['admin_year']; } // Get total count for pagination $count_sql = "SELECT COUNT(*) as total FROM students_info" . $where_clause; $count_stmt = $DBcon->prepare($count_sql); $count_stmt->execute($params); $total_result = $count_stmt->fetch(PDO::FETCH_ASSOC); $total_records = $total_result['total']; $total_pages = ceil($total_records / $per_page); // Calculate offset $offset = ($page - 1) * $per_page; // Get students with pagination $sql = "SELECT * FROM students_info" . $where_clause . " ORDER BY sn DESC LIMIT :offset, :per_page"; $stmt = $DBcon->prepare($sql); // Bind parameters foreach ($params as $key => $value) { $stmt->bindValue($key, $value); } $stmt->bindValue(':offset', $offset, PDO::PARAM_INT); $stmt->bindValue(':per_page', $per_page, PDO::PARAM_INT); $stmt->execute(); $students = $stmt->fetchAll(PDO::FETCH_ASSOC); return [ 'students' => $students, 'total_records' => $total_records, 'total_pages' => $total_pages, 'current_page' => $page ]; } catch (PDOException $e) { error_log("Get all students error: " . $e->getMessage()); return [ 'students' => [], 'total_records' => 0, 'total_pages' => 0, 'current_page' => 1 ]; } } function getStudent($id) { global $DBcon; try { $sql = "SELECT * FROM students_info WHERE sn = :id"; $stmt = $DBcon->prepare($sql); $stmt->execute([':id' => intval($id)]); $result = $stmt->fetch(PDO::FETCH_ASSOC); return $result; } catch (PDOException $e) { error_log("Get student error: " . $e->getMessage()); return false; } } function createStudent($data, $files) { global $DBcon; try { $image_path = handleImageUpload($files, $data); $sql = "INSERT INTO students_info (fullname, regno, class_id, admin_year, image) VALUES (:fullname, :regno, :class_id, :admin_year, :image)"; $stmt = $DBcon->prepare($sql); $result = $stmt->execute([ ':fullname' => sanitize_input($data['fullname']), ':regno' => sanitize_input($data['regno']), ':class_id' => sanitize_input($data['class_id']), ':admin_year' => sanitize_input($data['admin_year']), ':image' => $image_path ]); return $result; } catch (PDOException $e) { error_log("Create student error: " . $e->getMessage()); return false; } } function updateStudent($data, $files) { global $DBcon; try { // Get current student data first $current_student = getStudent($data['id']); if (!$current_student) { return false; } // Handle image upload $image_path = handleImageUpload($files, $data); // If no new image was uploaded, keep the current image if ($image_path === '') { $image_path = $current_student['image']; } else if ($image_path !== false) { // New image was uploaded successfully, delete old image if it exists if (!empty($current_student['image']) && file_exists('../' . $current_student['image'])) { unlink('../' . $current_student['image']); } } else { // Image upload failed $image_path = $current_student['image']; } $sql = "UPDATE students_info SET fullname = :fullname, regno = :regno, class_id = :class_id, admin_year = :admin_year, image = :image WHERE sn = :id"; $stmt = $DBcon->prepare($sql); $params = [ ':fullname' => sanitize_input($data['fullname']), ':regno' => sanitize_input($data['regno']), ':class_id' => sanitize_input($data['class_id']), ':admin_year' => sanitize_input($data['admin_year']), ':image' => $image_path, ':id' => intval($data['id']) ]; $result = $stmt->execute($params); return $result; } catch (PDOException $e) { error_log("Update student error: " . $e->getMessage()); return false; } } function handleImageUpload($files, $data) { // Check for webcam image first if (!empty($data['webcam_image']) && $data['webcam_image'] !== 'data:,') { return saveWebcamImage($data['webcam_image']); } // Check for file upload if (isset($files['image_upload']) && $files['image_upload']['error'] === UPLOAD_ERR_OK) { return saveUploadedImage($files['image_upload']); } // No image provided - return empty string return ''; } function saveWebcamImage($base64_image) { $upload_dir = '../uploads/students/'; // Create upload directory if it doesn't exist if (!file_exists($upload_dir)) { mkdir($upload_dir, 0755, true); } // Extract base64 data if (preg_match('/^data:image\/(\w+);base64,/', $base64_image, $type)) { $image_data = substr($base64_image, strpos($base64_image, ',') + 1); $type = strtolower($type[1]); // jpg, png, gif if (!in_array($type, ['jpg', 'jpeg', 'png', 'gif'])) { return false; } $image_data = base64_decode($image_data); if ($image_data === false) { return false; } } else { return false; } $filename = 'student_' . uniqid() . '.' . $type; $filepath = $upload_dir . $filename; if (file_put_contents($filepath, $image_data)) { return 'uploads/students/' . $filename; } return false; } function saveUploadedImage($file) { $upload_dir = '../uploads/students/'; $allowed_types = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif']; $max_size = 2 * 1024 * 1024; // 2MB // Create upload directory if it doesn't exist if (!file_exists($upload_dir)) { mkdir($upload_dir, 0755, true); } // Validate file if (!in_array($file['type'], $allowed_types)) { return false; } if ($file['size'] > $max_size) { return false; } // Generate unique filename $extension = pathinfo($file['name'], PATHINFO_EXTENSION); $filename = 'student_' . uniqid() . '.' . $extension; $filepath = $upload_dir . $filename; if (move_uploaded_file($file['tmp_name'], $filepath)) { return 'uploads/students/' . $filename; } return false; } function deleteStudent($id) { global $DBcon; try { // Get student image path to delete the file $student = getStudent($id); if ($student && !empty($student['image']) && file_exists('../' . $student['image'])) { unlink('../' . $student['image']); } $sql = "DELETE FROM students_info WHERE sn = :id"; $stmt = $DBcon->prepare($sql); return $stmt->execute([':id' => intval($id)]); } catch (PDOException $e) { error_log("Delete student error: " . $e->getMessage()); return false; } } // Generate CSRF token $csrf_token = generate_csrf_token(); // Get classes and academic years $classes = getClasses(); $academic_years = getAcademicYears(); // Initialize variables $action = isset($_GET['action']) ? sanitize_input($_GET['action']) : 'list'; $id = isset($_GET['id']) ? intval($_GET['id']) : 0; $message = ''; $message_type = ''; $student = null; // Handle form submissions if ($_SERVER['REQUEST_METHOD'] === 'POST') { // Validate CSRF token if (!validate_csrf_token($_POST['csrf_token'])) { $message = 'Security token validation failed.'; $message_type = 'error'; } else { // Process different actions switch ($_POST['action']) { case 'create': $result = createStudent($_POST, $_FILES); if ($result) { $message = 'Student created successfully.'; $message_type = 'success'; $action = 'list'; } else { $message = 'Failed to create student. Please try again.'; $message_type = 'error'; } break; case 'update': $result = updateStudent($_POST, $_FILES); if ($result) { $message = 'Student updated successfully.'; $message_type = 'success'; $action = 'list'; } else { $message = 'Failed to update student. Please try again.'; $message_type = 'error'; } break; case 'delete': $result = deleteStudent($_POST['id']); if ($result) { $message = 'Student deleted successfully.'; $message_type = 'success'; } else { $message = 'Failed to delete student. Please try again.'; $message_type = 'error'; } break; case 'bulk_delete': if (isset($_POST['selected_students']) && is_array($_POST['selected_students'])) { $success_count = 0; $error_count = 0; foreach ($_POST['selected_students'] as $student_id) { if (deleteStudent($student_id)) { $success_count++; } else { $error_count++; } } if ($success_count > 0) { $message = "Successfully deleted $success_count student(s)."; $message_type = 'success'; if ($error_count > 0) { $message .= " Failed to delete $error_count student(s)."; } } else { $message = 'Failed to delete selected students.'; $message_type = 'error'; } } else { $message = 'No students selected for deletion.'; $message_type = 'error'; } break; } } } // If editing, get student data if ($action === 'edit') { $student = getStudent($id); if (!$student) { $message = 'Student not found.'; $message_type = 'error'; $action = 'list'; } } // Get filter parameters $filter_class = isset($_GET['filter_class']) ? sanitize_input($_GET['filter_class']) : ''; $filter_year = isset($_GET['filter_year']) ? sanitize_input($_GET['filter_year']) : ''; $current_page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1; // Build filters array $filters = []; if (!empty($filter_class)) { $filters['class_id'] = $filter_class; } if (!empty($filter_year)) { $filters['admin_year'] = $filter_year; } // Get students with filters and pagination $students_data = getAllStudents($filters, $current_page, 25); $students = $students_data['students']; $total_records = $students_data['total_records']; $total_pages = $students_data['total_pages']; ?> Student Management - School Admin
Clear
Showing of records
0): ?>
# Image Full Name Registration No Class Admission Year Actions
Student Image

No students found. Try changing your filters or clear all filters. Add the first student.

1): ?>
Upload File Take Photo Current Image
Max file size: 2MB. Allowed types: JPG, JPEG, PNG, GIF
Current Image

Current student image